export class Com {
  private static instance: null | Com = null;
  private connector: null | HTMLElement = null;
  private name: null | string = null;
  private receiver: null | ((data: any) => void) = null;
  private sendTo: null | string = null;

  private constructor(name: string, sendTo: string) {
    this.name = name;
    this.sendTo = sendTo;
    this.init();
    // this.daemon();
  }

  private log(...args: any) {
    if (window._console) {
      _console.log(...args, document.title);
    } else {
      console.log(...args, document.title);
    }
  }

  public static getInstance(name: string, sendTo: string) {
    if (!Com.instance) Com.instance = new Com(name, sendTo);
    return Com.instance;
  }

  public reset() {
    this.init();
  }

  private init() {
    this.connector = document.documentElement;
    this.connector.addEventListener("to" + this.name, this.receive.bind(this));
  }

  public setReceiver(receiver: (args: any) => void) {
    this.receiver = receiver;
  }

  private receive(data: any) {
    if (!this.receiver) {
      // console.log("message is not receive properly... ", data.detail);
      this.log("message is not receive properly... ", data.detail);
      return;
    }
    // this.log(data, "receive");
    this.receiver(data.detail);
  }

  public dispatch(data: any) {
    if (this.sendTo === null)
      throw Error("please specific receiver of this message!");
    // this.log(data, "dispatch");
    this.send(this.sendTo, data);
  }
  public send(name: string, data: any) {
    if (!this.connector) {
      console.error("connector not ready");
      return;
    }
    const ev = new CustomEvent("to" + name, {
      detail: data,
    });
    this.connector.dispatchEvent(ev);
  }
}
